package com.atguigu.juc;

/**
 * @author admin
 *
 * 题目：判断打印的是“one”还是“two”
 *
 * 1.两个普通同步方法，两个线程，标准打印                     --> one two
 * 2.新增 Thread.sleep() 给 getOne()                    --> one two
 * 3.新增普通方法 getThree()                             --> three one two
 * 4.两个普通同步方法，两个 Number 对象                     --> two one
 * 5.修改 getOne() 为静态同步方法                         --> two one
 * 6.修改两个方法均为静态同步方法，一个Number对象             --> one two
 * 7.一个静态同步方法，一个非静态同步方法，两个Number对象       --> two one
 * 8.两个静态同步方法，两个Number对象                       --> one two
 *
 * 线程八锁的关键：
 * ①非静态方法的锁默认为 this，静态方法的锁为 对应的 Class 实例
 * ②某一时刻内，只能有一个线程持有锁，无论有几个方法
 */
public class TestThread8Monitor {

    public static void main(String[] args) {
        Number1 number1 = new Number1();
        Number2 number2 = new Number2();
        Number3 number3 = new Number3();
        Number4 number4 = new Number4();
        Number4 number4_1 = new Number4();
        Number5 number5 = new Number5();
        Number6 number6 = new Number6();
        Number7 number7 = new Number7();
        Number7 number7_1 = new Number7();
        Number8 number8 = new Number8();
        Number8 number8_1 = new Number8();

        /*
        锁1
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number1.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number1.getTwo();
            }
        }).start();

        /*
        锁2
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number2.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number2.getTwo();
            }
        }).start();

        /*
        锁3
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number3.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number3.getTwo();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number3.getThree();
            }
        }).start();

        /*
        锁4
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number4.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number4_1.getTwo();
            }
        }).start();

        /*
        锁5
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number5.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number5.getTwo();
            }
        }).start();

        /*
        锁6
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number6.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number6.getTwo();
            }
        }).start();

        /*
        锁7
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number7.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number7_1.getTwo();
            }
        }).start();

        /*
        锁8
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                number8.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number8_1.getTwo();
            }
        }).start();

    }
}

class Number1 {

    public synchronized void getOne() {
        System.out.println("one");
    }

    public synchronized void getTwo() {
        System.out.println("two");
    }
}

class Number2 {

    public synchronized void getOne() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public synchronized void getTwo() {
        System.out.println("two");
    }
}

class Number3 {

    public synchronized void getOne() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public synchronized void getTwo() {
        System.out.println("two");
    }

    public void getThree() {
        System.out.println("three");
    }
}

class Number4 {

    public synchronized void getOne() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public synchronized void getTwo() {
        System.out.println("two");
    }

}

class Number5 {

    public static synchronized void getOne() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public synchronized void getTwo() {
        System.out.println("two");
    }
}

class Number6 {

    public static synchronized void getOne() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public static synchronized void getTwo() {
        System.out.println("two");
    }
}

class Number7 {

    public static synchronized void getOne() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public synchronized void getTwo() {
        System.out.println("two");
    }
}

class Number8 {

    public static synchronized void getOne() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public static synchronized void getTwo() {
        System.out.println("two");
    }
}
